#pragma once

using namespace System;

public delegate void f(int);

public ref struct E 
{
	f^ _E;
public:
	E() 
	{
		_E = nullptr;
	}
	void handler(int i) 
	{
		System::Console::WriteLine(i);
	}

	event f^ MyEvent 
	{
	public:
		void add(f^ d) 
		{
		  if(nullptr ==_E)
			_E += d;
		}
		void remove(f^ d)
		{
			if(_E != nullptr)
				_E -= d;
		}
	protected:
		void raise(int i) 
		{
			if (_E)
			{
				_E->Invoke(i);
			}
		}
	}

   // a member function to access all evednt methods
	static void Go() 
	{
	  E^ pE = gcnew E;
	  pE->MyEvent += gcnew f(pE, &E::handler);
	  pE->MyEvent(17);   // prints 17
	  pE->MyEvent -= gcnew f(pE, &E::handler);
	  pE->MyEvent(27);   // no output
	}
	void Go2() 
	{
		MyEvent += gcnew f(this, &E::handler);
		MyEvent(37);
	}
};

void Test2() 
{
   E::Go();
   E e;
   e.Go2();

  E^ pE = gcnew E;
  pE->MyEvent += gcnew f(pE, &E::handler);
  // raise can not be accessible.
  // pE->MyEvent(47);  
}